package lunchy.data.classes;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import lunchy.data.interfaces.ILunchyMenu;
import lunchy.data.interfaces.ILunchyMenuDAO;
import lunchy.data.interfaces.ILunchyMenuGroup;
import lunchy.data.interfaces.ILunchyMenuItem;

public class CLunchyXMLMenuDAO implements ILunchyMenuDAO
{
	private Document data = null; 
	
	public CLunchyXMLMenuDAO(Document data)
	{
		this.data = data;
	}
	
	private ILunchyMenu getMenuItems(boolean activeOnly)
	{
		if(data != null)
		{
			ILunchyMenu menu = new CLunchyMenu();

			Node menuNode = data.getFirstChild();
			NodeList menuGroupsNodeList = menuNode.getChildNodes();

			for (int i = 0; i < menuGroupsNodeList.getLength(); i++)
			{
				Node groupNode = menuGroupsNodeList.item(i);
				
				if(groupNode.getNodeName() == "group")
				{
					NamedNodeMap groupAttributes = groupNode.getAttributes();
					
					Integer groupId = Integer.parseInt(groupAttributes.getNamedItem("id").getNodeValue());
					
					menu.setMaxGroupId(groupId);
					
					ILunchyMenuGroup group = new CLunchyMenuGroup(groupId, groupAttributes.getNamedItem("name").getNodeValue());
					NodeList menuItemsNodeList = groupNode.getChildNodes();

					for (int j = 0; j < menuItemsNodeList.getLength(); j++)
					{
						Node itemNode = menuItemsNodeList.item(j);
						
						if(itemNode.getNodeName() == "item")
						{
							NamedNodeMap itemAttributes = itemNode.getAttributes();
							
							boolean isActive = itemAttributes.getNamedItem("active").getNodeValue().equals("true");
							
							Integer itemId = Integer.parseInt(itemAttributes.getNamedItem("id").getNodeValue());
							
							menu.setMaxItemId(itemId);
							
							if(!activeOnly || isActive)
								group.addMenuGroupItem(new CLunchyMenuItem(itemId, itemAttributes.getNamedItem("name").getNodeValue(), Integer.parseInt(itemAttributes.getNamedItem("price").getNodeValue()), isActive));
						}
					}
					
					if(group.getMenuGroupItemsCount() > 0 || !activeOnly)
						menu.addMenuGroup(group);
				}
			}
			
			return menu;
		}
		else
		{
			return null;
		}
	}
	
	public ILunchyMenu getActiveMenuItems()
	{	
		return getMenuItems(true);
	}

	public ILunchyMenu getAllMenuItems()
	{
		return getMenuItems(false);
	}

	public boolean saveMenu(ILunchyMenu menu)
	{
		//Clear XML
		Node rootNode = data.getFirstChild();
		data.removeChild(rootNode);
		
		ArrayList<ILunchyMenuGroup> menuGroups = menu.getMenuGroups();
		
		Element rootElement = data.createElement("menu");
		
		for (ILunchyMenuGroup menuGroup : menuGroups)
		{
			Element groupElement = data.createElement("group");
			
			groupElement.setAttribute("id", menuGroup.getId().toString());
			groupElement.setAttribute("name", menuGroup.getName());
			
			rootElement.appendChild(groupElement);
			
			List<ILunchyMenuItem> menuItems = menuGroup.getItems();
			
			for (ILunchyMenuItem menuItem : menuItems)
			{
				Element itemElement = data.createElement("item");
				
				itemElement.setAttribute("id", menuItem.getId().toString());
				itemElement.setAttribute("name", menuItem.getName());
				itemElement.setAttribute("price", menuItem.getPrice().toString());
				itemElement.setAttribute("active", menuItem.isActive() ? "true" : "false");
				
				groupElement.appendChild(itemElement);
			}
		}
		
		data.appendChild(rootElement);

		try
		{
			TransformerFactory transformerFactory = TransformerFactory.newInstance();
			Transformer transformer = transformerFactory.newTransformer();
			DOMSource source = new DOMSource(data);
			StreamResult result = new StreamResult(new File("data/menu.xml"));
			transformer.transform(source, result);
		}
		catch (TransformerConfigurationException e)
		{
			e.printStackTrace();
		}
		catch (TransformerException e)
		{
			e.printStackTrace();
		}
		
		return true;
	}
}
